using System;
using System.Collections.Generic;
using System.Text;

namespace VisualizationPackage.FileLoader
{
    public class Util
    {
        internal static Format ParseFormat(string format)
        {
            if (format.ToLower() == Format.FBlock.ToString().ToLower())
                return Format.FBlock;
            if (format.ToLower() == Format.FPoint.ToString().ToLower())
                return Format.FPoint;
            return Format.FPoint;
        }

        internal static ElementType ParseElementType(string elementType)
        {
            ElementType et = ElementType.Brick;
            while (et != ElementType.Triangle)
            {
                if (et.ToString().ToLower() == elementType.ToLower())
                    return et;
                et++;
            }
            return ElementType.Quadrilateral;
        }
        public static Vertex Normal(Vertex v0, Vertex v1, Vertex v2)
        {
            Vertex V1 = v1 - v0;
            Vertex V2 = v2 - v0;
            return V1 * V2;
        }

        public static Vertex Interpolate(Visualization.Element element, Vertex vertex, Visualization.Zone zone, string distribution)
        {
            double totalValue = 0;
            vertex[distribution] = 0;
            for (int j = 0; j < element.Faces.Length; j++)
            {
                Visualization.Face face = zone.Faces[element.Faces[j]];
                for (int i = 0; i < face.Vertices.Length; i++)
                {
                    double val = ((new Vertex(zone.Vertices[face.Vertices[i]]) - vertex) as Vertex).Magnitude();
                    totalValue += val;
                }
            }
            for (int j = 0; j < element.Faces.Length; j++)
            {
                Visualization.Face face = zone.Faces[element.Faces[j]];
                for (int i = 0; i < face.Vertices.Length; i++)
                {
                    double val = ((new Vertex(zone.Vertices[face.Vertices[i]]) - vertex) as Vertex).Magnitude();
                    val /= totalValue;
                    vertex[distribution] += (1 - val) * zone.Vertices[face.Vertices[i]].Data[GlobalVariables.Get(distribution)];
                    //value += zone.Vertices[face.Vertices[i]].Data[GlobalVariables.Get(distribution)];
                }
            }

            //vertex[distribution] = value / count;
            return vertex;
        }
        public static Vertex InterpolateVector(Visualization.Element element, Vertex vertex, Visualization.Zone zone, string u, string v, string w)
        {
            double totalValue = 0;
            vertex[u] = 0;
            vertex[v] = 0;
            vertex[w] = 0;
            for (int j = 0; j < element.Faces.Length; j++)
            {
                Visualization.Face face = zone.Faces[element.Faces[j]];
                for (int i = 0; i < face.Vertices.Length; i++)
                {
                    double val = ((new Vertex(zone.Vertices[face.Vertices[i]]) - vertex) as Vertex).Magnitude();
                    totalValue += val;
                }
            }
            for (int j = 0; j < element.Faces.Length; j++)
            {
                Visualization.Face face = zone.Faces[element.Faces[j]];
                for (int i = 0; i < face.Vertices.Length; i++)
                {
                    double val = ((new Vertex(zone.Vertices[face.Vertices[i]]) - vertex) as Vertex).Magnitude();
                    val /= totalValue;
                    val = 1 - val;
                    vertex[u] += val * zone.Vertices[face.Vertices[i]].Data[GlobalVariables.Get(u)];
                    vertex[v] += val * zone.Vertices[face.Vertices[i]].Data[GlobalVariables.Get(v)];
                    vertex[w] += val * zone.Vertices[face.Vertices[i]].Data[GlobalVariables.Get(w)];
                    //value += zone.Vertices[face.Vertices[i]].Data[GlobalVariables.Get(distribution)];
                }
            }
            //float mag = (float)Math.Sqrt(vertex[u] * vertex[u] + vertex[v] * vertex[v] + vertex[w] * vertex[w]);
            //vertex[u] /= mag;
            //vertex[v] /= mag;
            //vertex[w] /= mag;
            //vertex[distribution] = value / count;
            return vertex;
        }
        public static double Modulus(Visualization.Vertex p1)
        {
            return Math.Sqrt(p1.Position.x * p1.Position.x + p1.Position.y * p1.Position.y + p1.Position.z * p1.Position.z);
        }
        public static Vertex CubicBezier(float t, Vertex p0, Vertex p1, Vertex p2, Vertex p3)
        {
            double ax, bx, cx;
            double ay, by, cy;
            double az, bz, cz;
            double tSquared, tCubed;
            Vertex result = new Vertex();

            /* calculate the polynomial coefficients */
            cx = 3.0 * (p1.X - p0.X);
            bx = 3.0 * (p2.X - p1.X) - cx;
            ax = p3.X - p0.X - cx - bx;

            cy = 3.0 * (p1.Y - p0.Y);
            by = 3.0 * (p2.Y - p1.Y) - cy;
            ay = p3.Y - p0.Y - cy - by;

            cz = 3.0 * (p1.Z - p0.Z);
            bz = 3.0 * (p2.Z - p1.Z) - cz;
            az = p3.Z - p0.Z - cz - bz;
            /* calculate the curve point at parameter value t */

            tSquared = t * t;
            tCubed = tSquared * t;

            result.X = (ax * tCubed) + (bx * tSquared) + (cx * t) + p0.X;
            result.Y = (ay * tCubed) + (by * tSquared) + (cy * t) + p0.Y;
            result.Z = (az * tCubed) + (bz * tSquared) + (cz * t) + p0.Z;

            return result;
        }
    }
}
